import React, { Component } from "react";
import { Row, Button, Col, Input, notification } from "antd";
import Proptypes from "prop-types";
import { FormattedMessage } from "react-intl";
import intl from "react-intl-universal";
import messages from "@i18n/messages";
import TYPE, { isForm } from "@design/constant/component-type";
import { CopyToClipboard } from "react-copy-to-clipboard";
import {
  createInput,
  createCheckbox,
  createTextArea,
  createSelect,
  createInputNumber,
  createCaculateOptions,
  createQueryOptions,
} from "./factory";
import {
  TextAreaProperties,
  SelectProperties,
  TextInputProperties,
  TextProperties,
  RadioProperties,
  CheckboxProperties,
  TableProperties,
  DatePickerProperties,
} from "./component";

class PropertyPanel extends Component {
  static propTypes = {
    node: Proptypes.object.isRequired,
    editor: Proptypes.object.isRequired,
  };

  state = {
    node: undefined,
    data: undefined,
  };

  constructor(props) {
    super(props);
    this.originalData = props.node.data;
    this.state = {
      node: props.node,
      data: props.node.data,
      style: props.node.style,
    };
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.node !== prevState.node) {
      return {
        node: nextProps.node,
        data: nextProps.node.data,
      };
    }
    return null;
  }

  componentDidUpdate(prevProps) {
    if (prevProps.node !== this.props.node) {
      this.originalData = this.props.node.data;
    }
  }

  getInputOptions = (data, property) => {
    return {
      size: "small",
      onChange: this.onChange,
      onEnter: this.onEnter,
      data,
      property,
      getter: (data, property) => data.get(property),
    };
  };

  onChange = (value, property) => {
    let data;
    if (Array.isArray(property)) {
      data = this.state.data.setIn(property, value);
    } else {
      data = this.state.data.set(property, value);
    }
    this.setState({
      data,
    });
  };

  onEnter = (value, property) => {
    let data;
    if (Array.isArray(property)) {
      data = this.state.data.setIn(property, value);
    } else {
      data = this.state.data.set(property, value);
    }
    const { editor, node } = this.props;
    editor.updateNode(node, { data });
  };

  onSubmitChange = () => {
    const { data } = this.state;
    const { editor, node } = this.props;
    editor.updateNode(node, { data });
  };

  onReset = () => {
    const { editor, node } = this.props;
    editor.updateNode(node, { data: this.originalData });
  };

  renderImage = () => {
    const { data } = this.state;
    return (
      <>
        {/* <Row className="row">
          <span className="label">Static image</span>
        </Row> */}
        <Row className="row">
          <div className="label">
            <FormattedMessage {...messages.propertyPanelImage.url} />
          </div>
          {createInput(this.getInputOptions(data, "src"))}
        </Row>
        <Row className="row">
          <div className="label">
            <FormattedMessage {...messages.propertyPanelImage.alt} />
          </div>
          {createInput(this.getInputOptions(data, "alt"))}
        </Row>
      </>
    );
  };

  renderCalculate = () => {
    const { data } = this.state;
    const getSelectOptions = (property, options) => ({
      onChange: this.onEnter,
      data,
      property,
      getter: (data, property) => {
        return data.get(property); 
      },
      options,
    });
    return (
      <>
        <Row className="row">
          <Col span={10}>
            <div className="label">
              <FormattedMessage {...messages.propertyPanelLabeltext} />
            </div>
          </Col>
          <Col span={14}>
            {createInput(this.getInputOptions(data, "label"))}
          </Col>
        </Row>
        <Row className="row">
          <Col span={10}>
            <span className="label">
              <FormattedMessage {...messages.propertyPanelLabelmargin} />
            </span>
          </Col>
          <Col span={14}>
            {createInputNumber(this.getInputOptions(data, "labelMargin"))}
          </Col>
        </Row>
        <Row className="row">
          <Col span={10}>
            <span className="label">
              <FormattedMessage {...messages.propertyPanelLabelalign} />
            </span>
          </Col>
          <Col span={14}>
            {createSelect(
              getSelectOptions("labelAlign", [
                { label: "顶部对齐", value: "top" },
                { label: "居中对齐", value: "middle" },
                { label: "底部对齐", value: "bottom" },
              ])
            )}
          </Col>
        </Row>
        <Row className="row">
          <div className="label">
            <FormattedMessage {...messages.propertyPanelCalculate.start} />
          </div>
          {createInput(this.getInputOptions(data, "start"))}
        </Row>
        <Row className="row">
          <div className="label">
            <FormattedMessage {...messages.propertyPanelCalculate.end} />
          </div>
          {createInput(this.getInputOptions(data, "end"))}
        </Row>
          {createCaculateOptions({
            onChange: this.onEnter,
            onUpdate: this.onEnter,
            data,
          })}
      </>
    );
  };

  stylechange = (value, property) => {
    const { style } = this.state;
    const temp = style.set(property, value);
    this.setState({
      style: temp,
    });
  };

  renderForm = () => {
    if (!isForm(this.state.node.type)) {
      return null;
    }
    const { data } = this.state;
    const getCheckboxOptions = property => {
      return {
        onChange: this.onEnter,
        data,
        property,
        getter: (data, property) => !!data.get(property),
      };
    };
    const getSelectOptions = (property, options) => ({
      onChange: this.onEnter,
      data,
      property,
      getter: (data, property) => data.get(property),
      options,
    });
    return (
      <>
        <Row
          className="row" type="flex"
          justify="space-between"
        >
          <span className="label">
            <FormattedMessage {...messages.propertyPanelRequired} />
          </span>
          {createCheckbox(getCheckboxOptions("required"))}
        </Row>
        <Row className="row">
          <Col span={10}>
            <span className="label">
              <FormattedMessage {...messages.propertyPanelLabeltext} />
            </span>
          </Col>
          <Col span={14}>
            {createInput(this.getInputOptions(data, "label"))}
          </Col>
        </Row>
        <Row className="row">
          <Col span={10}>
            <span className="label">
              <FormattedMessage {...messages.propertyPanelLabelmargin} />
            </span>
          </Col>
          <Col span={14}>
            {createInputNumber(this.getInputOptions(data, "labelMargin"))}
          </Col>
        </Row>
        <Row className="row">
          <Col span={10}>
            <span className="label">
              <FormattedMessage {...messages.propertyPanelLabelalign} />
            </span>
          </Col>
          <Col span={14}>
            {createSelect(
              getSelectOptions("labelAlign", [
                { label: "顶部对齐", value: "top" },
                { label: "居中对齐", value: "middle" },
                { label: "底部对齐", value: "bottom" },
              ])
            )}
          </Col>
        </Row>
      </>
    );
  };

  render() {
    const { node, data } = this.state;
    let children = null;
    switch (node.type) {
      case TYPE.TEXT_INPUT:
        children = (
          <TextInputProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      case TYPE.QUERYPICKER:         
        children = createQueryOptions({          
          data: this.state.data,
          onChange: this.onChange,
          onUpdate: this.onEnter,          
        });  
        break;
      case TYPE.DIVIDER:        
        // children = (
        //   <>
        //     <Row className="row">
        //       <Col span={10}>
        //         <span className="label">
        //           <FormattedMessage {...messages.stylePanel.height} />
        //         </span>
        //       </Col>
        //       <Col span={14}>
        //         {createInput(
        //           {
        //             size: "small",
        //             onChange: this.stylechange,
        //             onEnter: this.onEnter,
        //             data: node.style,
        //             property: "height",
        //             getter: (data, property) => data.get(property),
        //           }
        //         )}
        //       </Col>
        //     </Row>
        //   </>
        // );
        break;
      case TYPE.TEXT_AREA:
        children = (
          <TextAreaProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      case TYPE.SELECT:
        children = (
          <SelectProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      case TYPE.RADIO:
        children = (
          <RadioProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      case TYPE.CHECKBOX:
        children = (
          <CheckboxProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      case TYPE.TEXT:
        children = (
          <TextProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      case TYPE.IMAGE:
        children = this.renderImage();
        break;
      case TYPE.CALCULATE:
        children = this.renderCalculate();
        break;
      case TYPE.TABLE:
        children = (
          <TableProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      case TYPE.DATEPICKER:
        children = (
          <DatePickerProperties
            node={node}
            data={this.state.data}
            onChange={this.onChange}
            onUpdate={this.onEnter}
          />
        );
        break;
      default:
        break;
    }
    return (
      <div className="property-style-panel property-panel-detail">
        <Row className="row">
          <Col span={10}>
            <span className="label">
              <FormattedMessage {...messages.propertyPanelName} />
            </span>
          </Col>
          <Col span={14}>{createInput(this.getInputOptions(data, "name"))}</Col>
        </Row>
        <Row className="row">
          <Col span={10}>
            <span className="label">key</span>
          </Col>
          <CopyToClipboard
            onCopy={() =>
              notification.success({
                message: intl.get(messages.successNotification.copy.id),
              })
            }
            text={data.get("column")}
          >
            <Col span={14}>
              <Input value={data.get("column")} disabled />
            </Col>
          </CopyToClipboard>
        </Row>
        <Row className="row">
          <div className="label">
            <FormattedMessage {...messages.propertyPanelDescription} />
          </div>
          {createTextArea(this.getInputOptions(data, "description"))}
        </Row>
        {this.renderForm()}
        {children}
        <Row className="row submit-btn">
          <Button onClick={this.onSubmitChange}>
            <FormattedMessage {...messages.propertyPanelUpdate} />
          </Button>
          <Button onClick={this.onReset}>
            <FormattedMessage {...messages.propertyPanelReset} />
          </Button>
        </Row>
      </div>
    );
  }
}

export default PropertyPanel;
